CODv2 3.12 実例:PowerPCと80×86の命令
「美しさはすべからく見る人しだい」
概要
命令セットの設計者は、 MIPS に備わっている以上の強力な命令操作を持たせることがある
一般には、プログラムによって実行される命令数を減らそうともくろんでのことだが、単純さが犠牲になり、プログラムの実行に要する時間が長くなる危険がある。命令の実行速度が低下するからである
速度が低下する理由は、
クロック・サイクル時間が遅くなるか、
単純な命令列よりも多くのクロック・サイクル数が必要となるか、
このように、命令操作を複雑化する道を選ぶことは危険が伴う
そのような問題を避けるため、設計者は多くの命令を単純化する道を進んでいる
補足
CODv2 では PowerPC と 80x86 について触れているが、
CODv1 では VAX との比較が行われている
CODv1 第3章 「命令:マシンの言葉 」(上巻)
CODv1 3.8 MIPS とは異なる方式
CODv1 付録 E 「別方式の命令セット・アーキテクチャ VAX」(下巻)
CODv3 では Intel 80x86 という呼称が IA-32 になっている
PowerPC との比較は除かれている
CODv5 以降では ARMv7(32bit), ARMv8(64bit), RISC-V, そして x86 との比較が行われている
手元に版がないので、内容は不明
CODv2 実例:PowerPC の命令
IBM/Motolora PowerPC
(第3版では、項目が削除されている)
MIPS との比較
共通点
32個の整数レジスタ
すべての命令は 32 ビット
データ転送はロードおよびストアを通じてのみ可能
相違点
アドレシング・モードが2つ余計にある
命令操作が少し多い
追加された2つのアドレシング・モード
MIPS のアドレシング・モードについて
インデックス修飾アドレシング
indexed addressing
https://gyazo.com/687a514e6d89c4ba4f36f4e33e26200f
MIPS のアセンブリ・コード
code:exp3.12.1.asm
add $t0, $a0, $s3 # $a0 は配列のベース・アドレス、 $s3 はインデックスを表す
この2つの命令を1つの命令で置き換えるもの( PowerPC のアセンブリ・コード)
code:exp3.12.2.asm
ロード命令とストア命令の両方に適用できる
参考: ベース相対アドレシング
base addressing
https://gyazo.com/213e614d475aaebd188f931a87fe5777
ロード命令 lw とストア命令 sw
1つのレジスタに配列の基点(ベース・アドレス)、もう1つのレジスタに配列のインデックスを保持する
例 : lw $t0, 32($s3)
A[8] が一時レジスタ $t0 に代入される。(命令の定数部分 : 8, レジスタの内容 : $s3 )
データ転送命令中の定数をオフセット( offset )
アドレスを得るために加えるレジスタをベース・レジスタ( base register )と呼ぶ
$s3 を表す 19 は rs フィールドへ
$t0 を表す 8 は rt フィールドへ
オフセット 32 は address フィールドへ入れられる
lw 命令では rt フィールドは転送されるデータを受け取るデスティネーション・レジスタを表すことになる
table:exp3.3.2
field No. 1 2 3 4
filed name op rs rt adress
decimal 35 19 8 32
更新アドレシング
update addressing
https://gyazo.com/68f9ad8ca7a7ef42d0d44326fe099ba1
メモリ中の語の配列を順々に処理していくコード系列
そのような処理に頻出する1組のコードがある
語をロードし、それからベース・レジスタを繰り上げて、次の語を指すようにする処理
MIPS のアセンブリ・コード
code:exp3.12.3.asm
lw $t0, 4($s3) # メモリ$s3 + 4 を $t0 にロード addi $s3, $s3, 4 # $s3 = $s3 + 4
この2つの命令を1つの命令で置き換えるもの( PowerPC のアセンブリ・コード)
code:exp3.12.4.asm
lwu $t0, 4($s3) # メモリ$s3 + 4 を $t0 にロード、そして $s3 = $s3 + 4 ロード処理の一環として算出されたアドレスでレジスタが更新される
PowerPC の更新アドレシングは、ベース相対アドレシング、インデックス修飾アドレシングの両方、および、ロード命令、ストア命令に適用可能
PowerPC 特有の命令
PowerPC の命令は MIPS と同様のスタイルのアーキテクチャに基づいており、主として性能の観点から、単純な命令を高速に実行することに重きを置いているが、
いくつかの例外
複数の語をロード、および、ストアする命令
1つの命令で最大32個までの語を転送できる
この命令は、複数の語のロードと、複数の語のストアを、連続して実行することによって、メモリ中のロケーションを高速にコピーすることを意図している
こうした命令を使用すると、複数のレジスタをロード、または、ストアするときのコードサイズが抑えられる
ループの性能をあげるためのカウンタ・レジスタ
PowerPC には32個のレジスタと別に、特別のカウンタ・レジスタが用意されている
目的は for ループの性能を上げることにある
code:exp3.12.1.c
for (i = n; i !=0; i = i - 1)
{
/* loop の本体 */
}
レジスタを繰り下げ、 0 と比較し、レジスタの値が 0 でない間は分岐( loop )を繰り返すものとする
code:exp3.12.1.asm
loop: # for ループの初期化やループの本体
addi $t0, $t0, -1 # i = i -1 ( $t0 をデクリメント)
bne $t0, $zero, loop # $t0 が 0 でなければ loop に分岐
PowerPC には上記の代わりに、下記の単一の命令を使用することができる
code:exp3.12.2.asm
loop: # for ループの初期化やループの本体
bc Loop, ctr!=0 # $ctr = $ctr - 1
# $ctr が 0 でなければ loop に分岐
ハードウェアとソフトウェアのインターフェース 3.12.1
以上のような込み入った命令操作は、単純性を重んずべしとの指針に反する
そればかりではなく、コンパイラが生成したコードとうまく合致しない可能性がある
イレギュラーに対応するためには命令を汎用化する必要があり、そのためにオペランドを追加したりオプションを追加することにより、単純な命令の系統よりも遅くなる危険がある